<template>
  <div class="system-log-container">
    <el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
      <el-tab-pane label="操作日志" name="operation">
        <el-card class="log-card">
          <template #header>
            <div class="card-header">
              <div class="header-left">
                <el-input
                  v-model="operationQuery.search"
                  placeholder="搜索用户名/操作内容"
                  clearable
                  @keyup.enter="searchOperationLogs"
                  @clear="searchOperationLogs"
                >
                  <template #suffix>
                    <el-icon class="el-input__icon" @click="searchOperationLogs">
                      <Search />
                    </el-icon>
                  </template>
                </el-input>
                <el-date-picker
                  v-model="operationQuery.dateRange"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  :shortcuts="dateShortcuts"
                  @change="searchOperationLogs"
                  class="date-picker"
                />
              </div>
              <div class="header-right">
                <el-button type="primary" @click="exportOperationLogs">导出</el-button>
                <el-button type="danger" @click="clearOperationLogs" style="margin-right: 500px">清空</el-button>
              </div>
            </div>
          </template>
          
          <el-table
            :data="operationLogs"
            style="width: 100%"
            v-loading="loading.operation"
          >
            <el-table-column prop="id" label="日志编号" width="80" />
            <el-table-column prop="userName" label="用户名" width="120" />
            <el-table-column prop="ipAddress" label="IP地址" width="120" />
            <el-table-column prop="module" label="功能模块" width="120" />
            <el-table-column prop="action" label="操作类型" width="100">
              <template #default="scope">
                <el-tag :type="getActionTagType(scope.row.action)">
                  {{ scope.row.action }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="description" label="操作描述"  width="200"/>
            <el-table-column prop="result" label="操作结果" width="100">
              <template #default="scope">
                <el-tag :type="scope.row.result ? 'success' : 'danger'">
                  {{ scope.row.result ? '成功' : '失败' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="operationTime" label="操作时间" width="180" />
            <el-table-column label="操作" width="100">
              <template #default="scope">
                <el-button
                  size="small"
                  type="text"
                  @click="viewOperationDetail(scope.row)"
                >
                  详情
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          
          <!-- 分页 -->
          <div class="pagination-container">
            <el-pagination
              v-model:current-page="operationQuery.page"
              v-model:page-size="operationQuery.size"
              :page-sizes="[10, 20, 50, 100]"
              layout="total, sizes, prev, pager, next, jumper"
              :total="operationTotal"
              @size-change="handleOperationSizeChange"
              @current-change="handleOperationPageChange"
            />
          </div>
        </el-card>
      </el-tab-pane>
      
      <el-tab-pane label="登录日志" name="login">
        <el-card class="log-card">
          <template #header>
            <div class="card-header">
              <div class="header-left">
                <el-input
                  v-model="loginQuery.search"
                  placeholder="搜索用户名/IP地址"
                  clearable
                  @keyup.enter="searchLoginLogs"
                  @clear="searchLoginLogs"
                >
                  <template #suffix>
                    <el-icon class="el-input__icon" @click="searchLoginLogs">
                      <Search />
                    </el-icon>
                  </template>
                </el-input>
                <el-date-picker
                  v-model="loginQuery.dateRange"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  :shortcuts="dateShortcuts"
                  @change="searchLoginLogs"
                  class="date-picker"
                />
                <el-select
                  v-model="loginQuery.status"
                  placeholder="登录状态"
                  clearable
                  @change="searchLoginLogs"
                  class="status-select"
                >
                  <el-option label="成功" value="success" />
                  <el-option label="失败" value="failure" />
                </el-select>
              </div>
              <div class="header-right">
                <el-button type="primary" @click="exportLoginLogs">导出</el-button>
                <el-button type="danger" @click="clearLoginLogs">清空</el-button>
              </div>
            </div>
          </template>
          
          <el-table
            :data="loginLogs"
            style="width: 100%"
            v-loading="loading.login"
          >
            <el-table-column prop="id" label="日志编号" width="80" />
            <el-table-column prop="userName" label="用户名" width="120" />
            <el-table-column prop="ipAddress" label="IP地址" width="120" />
            <el-table-column prop="browser" label="浏览器" width="150" />
            <el-table-column prop="os" label="操作系统" width="150" />
            <el-table-column prop="status" label="状态" width="100">
              <template #default="scope">
                <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'">
                  {{ scope.row.status === 'success' ? '成功' : '失败' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="message" label="消息" />
            <el-table-column prop="loginTime" label="登录时间" width="180" />
          </el-table>
          
          <!-- 分页 -->
          <div class="pagination-container">
            <el-pagination
              v-model:current-page="loginQuery.page"
              v-model:page-size="loginQuery.size"
              :page-sizes="[10, 20, 50, 100]"
              layout="total, sizes, prev, pager, next, jumper"
              :total="loginTotal"
              @size-change="handleLoginSizeChange"
              @current-change="handleLoginPageChange"
            />
          </div>
        </el-card>
      </el-tab-pane>
    </el-tabs>
    
    <!-- 操作日志详情对话框 -->
    <el-dialog
      v-model="detailVisible"
      title="操作日志详情"
      width="700px"
    >
      <el-descriptions
        title="基本信息"
        :column="2"
        border
      >
        <el-descriptions-item label="用户名">{{ selectedLog.userName }}</el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ selectedLog.ipAddress }}</el-descriptions-item>
        <el-descriptions-item label="功能模块">{{ selectedLog.module }}</el-descriptions-item>
        <el-descriptions-item label="操作类型">
          <el-tag :type="getActionTagType(selectedLog.action)">
            {{ selectedLog.action }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="操作描述" :span="2">{{ selectedLog.description }}</el-descriptions-item>
        <el-descriptions-item label="操作结果">
          <el-tag :type="selectedLog.result ? 'success' : 'danger'">
            {{ selectedLog.result ? '成功' : '失败' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="操作时间">{{ selectedLog.operationTime }}</el-descriptions-item>
      </el-descriptions>
      
      <el-divider content-position="center">参数和响应</el-divider>
      
      <el-tabs>
        <el-tab-pane label="请求参数">
          <pre class="detail-code">{{ formatJson(selectedLog.requestParams) }}</pre>
        </el-tab-pane>
        <el-tab-pane label="响应结果">
          <pre class="detail-code">{{ formatJson(selectedLog.responseResult) }}</pre>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { logAPI } from '@/api/api'

export default {
  name: 'SystemLog',
  components: {
    Search
  },
  setup() {
    // 激活的选项卡
    const activeTab = ref('operation')
    
    // 操作日志数据
    const operationLogs = ref([])
    const operationTotal = ref(0)
    const operationQuery = reactive({
      page: 1,
      size: 10,
      search: '',
      dateRange: null,
      startTime: '',
      endTime: ''
    })
    
    // 登录日志数据
    const loginLogs = ref([])
    const loginTotal = ref(0)
    const loginQuery = reactive({
      page: 1,
      size: 10,
      search: '',
      status: '',
      dateRange: null,
      startTime: '',
      endTime: ''
    })
    
    // 日志详情
    const detailVisible = ref(false)
    const selectedLog = ref({})
    
    // 加载状态
    const loading = reactive({
      operation: false,
      login: false
    })
    
    // 日期快捷选项
    const dateShortcuts = [
      {
        text: '最近一周',
        value: (() => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
          return [start, end]
        })()
      },
      {
        text: '最近一个月',
        value: (() => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
          return [start, end]
        })()
      },
      {
        text: '最近三个月',
        value: (() => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
          return [start, end]
        })()
      }
    ]
    
    // 获取操作日志
    const fetchOperationLogs = async () => {
      loading.operation = true
      
      // 处理日期范围
      if (operationQuery.dateRange && operationQuery.dateRange.length === 2) {
        operationQuery.startTime = formatDate(operationQuery.dateRange[0])
        operationQuery.endTime = formatDate(operationQuery.dateRange[1])
      } else {
        operationQuery.startTime = ''
        operationQuery.endTime = ''
      }
      
      const params = {
        page: operationQuery.page,
        size: operationQuery.size,
        search: operationQuery.search || undefined,
        startTime: operationQuery.startTime || undefined,
        endTime: operationQuery.endTime || undefined
      }
      
      try {
        const response = await logAPI.getOperationLogs(params)
        
        if (response.success) {
          operationLogs.value = response.data.list || []
          operationTotal.value = response.data.totalItems || 0
        } else {
          ElMessage.error('获取操作日志失败: ' + response.message)
        }
      } catch (error) {
        console.error('获取操作日志失败:', error)
        ElMessage.error('获取操作日志失败: ' + (error.message || '未知错误'))
      } finally {
        loading.operation = false
      }
    }
    
    // 获取登录日志
    const fetchLoginLogs = async () => {
      loading.login = true
      
      // 处理日期范围
      if (loginQuery.dateRange && loginQuery.dateRange.length === 2) {
        loginQuery.startTime = formatDate(loginQuery.dateRange[0])
        loginQuery.endTime = formatDate(loginQuery.dateRange[1])
      } else {
        loginQuery.startTime = ''
        loginQuery.endTime = ''
      }
      
      const params = {
        page: loginQuery.page,
        size: loginQuery.size,
        search: loginQuery.search || undefined,
        status: loginQuery.status || undefined,
        startTime: loginQuery.startTime || undefined,
        endTime: loginQuery.endTime || undefined
      }
      
      try {
        const response = await logAPI.getLoginLogs(params)
        
        if (response.success) {
          loginLogs.value = response.data.list || []
          loginTotal.value = response.data.totalItems || 0
        } else {
          ElMessage.error('获取登录日志失败: ' + response.message)
        }
      } catch (error) {
        console.error('获取登录日志失败:', error)
        ElMessage.error('获取登录日志失败: ' + (error.message || '未知错误'))
      } finally {
        loading.login = false
      }
    }
    
    // 搜索操作日志
    const searchOperationLogs = () => {
      operationQuery.page = 1
      fetchOperationLogs()
    }
    
    // 搜索登录日志
    const searchLoginLogs = () => {
      loginQuery.page = 1
      fetchLoginLogs()
    }
    
    // 导出操作日志
    const exportOperationLogs = async () => {
      try {
        // 处理日期范围
        if (operationQuery.dateRange && operationQuery.dateRange.length === 2) {
          operationQuery.startTime = formatDate(operationQuery.dateRange[0])
          operationQuery.endTime = formatDate(operationQuery.dateRange[1])
        } else {
          operationQuery.startTime = ''
          operationQuery.endTime = ''
        }
        
        const params = {
          search: operationQuery.search || undefined,
          startTime: operationQuery.startTime || undefined,
          endTime: operationQuery.endTime || undefined
        }
        
        const response = await logAPI.exportOperationLogs(params)
        
        // 创建一个blob对象
        const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' })
        
        // 创建下载链接
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = '操作日志.xlsx'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        
        ElMessage.success('导出成功')
      } catch (error) {
        console.error('导出操作日志失败:', error)
        ElMessage.error('导出操作日志失败: ' + (error.message || '未知错误'))
      }
    }
    
    // 导出登录日志
    const exportLoginLogs = async () => {
      try {
        // 处理日期范围
        if (loginQuery.dateRange && loginQuery.dateRange.length === 2) {
          loginQuery.startTime = formatDate(loginQuery.dateRange[0])
          loginQuery.endTime = formatDate(loginQuery.dateRange[1])
        } else {
          loginQuery.startTime = ''
          loginQuery.endTime = ''
        }
        
        const params = {
          search: loginQuery.search || undefined,
          status: loginQuery.status || undefined,
          startTime: loginQuery.startTime || undefined,
          endTime: loginQuery.endTime || undefined
        }
        
        const response = await logAPI.exportLoginLogs(params)
        
        // 创建一个blob对象
        const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' })
        
        // 创建下载链接
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = '登录日志.xlsx'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        
        ElMessage.success('导出成功')
      } catch (error) {
        console.error('导出登录日志失败:', error)
        ElMessage.error('导出登录日志失败: ' + (error.message || '未知错误'))
      }
    }
    
    // 清空操作日志
    const clearOperationLogs = () => {
      ElMessageBox.confirm(
        '确定要清空所有操作日志吗？此操作将不可恢复！',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
      )
        .then(async () => {
          try {
            const response = await logAPI.clearOperationLogs()
            
            if (response.success) {
              ElMessage.success('清空操作日志成功')
              fetchOperationLogs()
            } else {
              ElMessage.error('清空操作日志失败: ' + response.message)
            }
          } catch (error) {
            console.error('清空操作日志失败:', error)
            ElMessage.error('清空操作日志失败: ' + (error.message || '未知错误'))
          }
        })
        .catch(() => {
          ElMessage.info('已取消操作')
        })
    }
    
    // 清空登录日志
    const clearLoginLogs = () => {
      ElMessageBox.confirm(
        '确定要清空所有登录日志吗？此操作将不可恢复！',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
      )
        .then(async () => {
          try {
            const response = await logAPI.clearLoginLogs()
            
            if (response.success) {
              ElMessage.success('清空登录日志成功')
              fetchLoginLogs()
            } else {
              ElMessage.error('清空登录日志失败: ' + response.message)
            }
          } catch (error) {
            console.error('清空登录日志失败:', error)
            ElMessage.error('清空登录日志失败: ' + (error.message || '未知错误'))
          }
        })
        .catch(() => {
          ElMessage.info('已取消操作')
        })
    }
    
    // 查看操作日志详情
    const viewOperationDetail = (log) => {
      selectedLog.value = { ...log }
      detailVisible.value = true
    }
    
    // 操作类型标签颜色
    const getActionTagType = (action) => {
      const typeMap = {
        '新增': 'success',
        '修改': 'primary',
        '删除': 'danger',
        '查询': 'info',
        '导出': 'warning',
        '导入': 'warning',
        '其他': ''
      }
      
      return typeMap[action] || ''
    }
    
    // 分页相关
    const handleOperationSizeChange = (newSize) => {
      operationQuery.size = newSize
      fetchOperationLogs()
    }
    
    const handleOperationPageChange = (newPage) => {
      operationQuery.page = newPage
      fetchOperationLogs()
    }
    
    const handleLoginSizeChange = (newSize) => {
      loginQuery.size = newSize
      fetchLoginLogs()
    }
    
    const handleLoginPageChange = (newPage) => {
      loginQuery.page = newPage
      fetchLoginLogs()
    }
    
    // 选项卡切换
    const handleTabClick = () => {
      if (activeTab.value === 'operation') {
        fetchOperationLogs()
      } else {
        fetchLoginLogs()
      }
    }
    
    // 工具函数：格式化日期
    const formatDate = (date) => {
      if (!date) return ''
      
      const d = new Date(date)
      const year = d.getFullYear()
      const month = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      
      return `${year}-${month}-${day}`
    }
    
    // 工具函数：格式化JSON
    const formatJson = (jsonStr) => {
      if (!jsonStr) return ''
      
      let jsonObj = jsonStr
      
      // 如果是字符串，尝试解析为对象
      if (typeof jsonStr === 'string') {
        try {
          jsonObj = JSON.parse(jsonStr)
        } catch (e) {
          return jsonStr
        }
      }
      
      // 格式化输出
      return JSON.stringify(jsonObj, null, 2)
    }
    
    onMounted(() => {
      fetchOperationLogs()
    })
    
    return {
      activeTab,
      operationLogs,
      operationTotal,
      operationQuery,
      loginLogs,
      loginTotal,
      loginQuery,
      loading,
      detailVisible,
      selectedLog,
      dateShortcuts,
      fetchOperationLogs,
      fetchLoginLogs,
      searchOperationLogs,
      searchLoginLogs,
      exportOperationLogs,
      exportLoginLogs,
      clearOperationLogs,
      clearLoginLogs,
      viewOperationDetail,
      getActionTagType,
      handleOperationSizeChange,
      handleOperationPageChange,
      handleLoginSizeChange,
      handleLoginPageChange,
      handleTabClick,
      formatJson
    }
  }
}
</script>

<style scoped>
.system-log-container {
  padding: 20px;
}

.log-card {
  margin-top: 10px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.header-right {
  display: flex;
  gap: 10px;
}

.date-picker {
  width: 340px;
}

.status-select {
  width: 120px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.detail-code {
  background-color: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  font-family: monospace;
  max-height: 300px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-all;
}
</style> 